<?php
//---------------------------------------------------------------------------------------------------
    require_once ($config['adodb']['path'] . 'adodb.inc.php');
    require_once ($config['adodb']['path'] . 'adodb-time.inc.php');
    require_once ($config['adodb']['path'] . 'adodb-active-record.inc.php');
    require_once ($config['adodb']['path'] . 'adodb-exceptions.inc.php');

    require_once($config['app_dir'] . '/includes/object.class.php');
    require_once($config['app_dir'] . '/includes/mailer.class.php');
    //---------------------------------------------------------------------------------------------------
    $ADODB_ASSOC_CASE = 0;
    //---------------------------------------------------------------------------------------------------
    class objDataBase {
            public $handler = false;
            private static $instance;

        private function  __construct() {
         global $config, $ADODB_CACHE_DIR;
            try {
               $this->handler = &ADONewConnection($config['db']['driver']);

               $this->handler->Connect($config['db']['host'],
                                           $config['db']['user'],
                                           $config['db']['password'],
                                           $config['db']['database']);
            } catch(exception $e) {

                if (true == $this->handler->debug ) {
                    adodb_pr($e);
                    adodb_backtrace($e->gettrace());
                }

                $AlertMailer = new objMailer();
                $AlertMailer->AddAddress($config['admin']['email']);
                $AlertMailer->isHTML( true );
                $AlertMailer->Subject = 'Error Alert: database';
                $AlertMailer->Body = 'DB Error: ' . $e->sql . ' ' . $e->msg;
                $AlertMailer->Send();

                die('DB Error: ' . $e->sql . ' ' . $e->msg);
            }//catch

            $this->handler->debug = $config['db']['debug'];
            $this->handler->execute("set names 'utf8';");//1251
            $this->handler->execute('set time_zone="-00:00";'); //XXX GMT timezone
            $this->handler->SetFetchMode(ADODB_FETCH_ASSOC);
            //$this->handler->execute("set names 'cp1251';");
            if ( $config['adodb']['cache_dir'] )
                $ADODB_CACHE_DIR = $config['adodb']['cache_dir'];
       }//constructor

       public static function GetInstance() {
            if (!isset(self::$instance)) {
                $c = __CLASS__;
                self::$instance = new $c;
            }
            return self::$instance;
       } //GetInstance

       public function __clone()    {
            throw new Exception('Cant clone singleton');
       } //clone

       public function setEncoding($charset='utf8') {
            $this->handler->execute("set names '".$charset."';");
       } //setEncoding

       public function getRecord($query, $params=array()) {
            try {
                $rs = $this->handler->Execute($query, $params);
            } catch(exception $e) {
                if (true == $this->handler->debug ) {
                    adodb_pr($e);
                    $e = adodb_backtrace($e->trace);
                }
                die('DB Error: '.$e->sql);
            }
            $data = false;
            if ( $rs ) {
                //$data = $rs->GetArray();
                if (function_exists("adodb_getall")) $data = adodb_getall($rs);
                    else $data = $rs->getArray();
                $data = $data[0];
            }
            return $data;
        } //getRecord

        public function Execute($sql) {
            return $this->handler->Execute($sql);
        } //Execute

       function __destruct() {
            $this->handler->Close();
       } //destructor

    }//class objDataBase
    //---------------------------------------------------------------------------------------------------
    abstract class objDBActiveRecord extends objObject {

            protected $_record = false;
            protected $_db = false;
            protected $_sql_querys = array();
            protected $_table;
            protected $_key;

        public function __construct() {
            $this->_db = objDataBase::GetInstance();
            ADOdb_Active_Record::SetDatabaseAdapter( $this->_db->handler );
            $this->Record();
        } //constructor

        public function ClassName() {
            return  __CLASS__;
        } //ClassName

        public function getID() {
            return $this->_record->{$this->_key};
        } //getID

        protected function Record() {
            if( $this->isRecordEmpty() ) {
                try {
                    $this->_record = new ADODB_Active_record( $this->_table );
                } catch(exceptions $e) {
                    if (true == $this->_db->handler->debug ) {
                        adodb_pr($e);
                        $e = adodb_backtrace($e->trace);
                    }
                    echo 'Error: '.$e->sql.' '.$e->getMessage();
                } //catch
            } // is record not started before

            if( $where=$this->BuildWhere() ) $this->_record->Load( $where );
        } //Record

        public function isField($aField) {
            return  !$this->isRecordEmpty() && array_key_exists($aField, get_object_vars($this->_record));
        } //isField

        public function isRecordEmpty() {
            return empty($this->_record) || false==$this->_record;
        } //isRecordEmpty

        protected function __get($aName) {
            $aName = strtolower($aName);

            if( $this->isField($aName) )  return $this->_record->{$aName};

            switch( $aName ) {
                //--------------------------------------------------
                case 'record':
                    return $this->_record;
                break;
                //--------------------------------------------------
            } //switch

        } //getter

        public function __set($aName, $aValue) {
            $aName = strtolower($aName);
            $this->Record();
            if( $this->isField($aName) ) $this->_record->{$aName} = $aValue;
        } //setter

        protected function BuildWhere() {
            return false;
        } //BuildWhere

        public function Save() {
            if( $this->isRecordEmpty() )  return false;
            return $this->_record->Save();
        } //Save

        public function Load($aID=false) {
            $this->Record();
            if( $aID && $this->_key && !$this->isRecordEmpty() )
                $this->_record->Load("$this->_key=$aID");
        } //Load

        public function Delete() {
            if( $this->isRecordEmpty() )  return false;
            return $this->_record->Delete();
        } //Delete

        public function Insert() {
            $this->Record();
            return $this->_record->Insert();
        } //Insert

        public function Update() {
            $this->Record();
            return $this->_record->Update();
        } //Update

        public function Replace() {
            $this->Record();
            return $this->_record->Replace();
        } //Replace

        public function isEmpty(){
            return  $this->isRecordEmpty() || ( $this->_key && !$this->_record->{$this->_key} );
        } //isEmpty

        protected function _sqls() {
            if( $where = $this->BuildWhere() ) $where = ' AND ' . $where;
            //-----------------------------------------------------------------------------
            $this->_sql_querys['list'] = " SELECT * FROM $this->_table WHERE (1=1) $where ";
        } //__sqls

    } //class objDBActiveRecord
//---------------------------------------------------------------------------------------------------
?>
